function [postStru,priorCell]=priorStruCreate(inStru)
% =========================================================================
% 
% priorStruCreate.m 
%
% Loads the prior for the coefficients and checks that 
% the calibrated parameters have been set properly  
%
% function [indp,con,calpr,alphap,betap]=loadprior(dist,lcone,lctwo); 
%
%% Inputs 
%  inStru 

% DIST     [Np 1] Cell array, Name of the densities for the full
%           parameter vector 
%           e.g. N (Normal), W (Wishart), B (Beta), I (Inverse Wishart), 
%                G (Gamma),  U (Uniform), E (Weibull), T (Truncated Beta) 
%                C (Calibrated) 
% LCONE     [Np 1] Vector, Location Parameter 1, e.g. Mean or Alpha
%
% LCTWO     [Np 1] Vector, Location Parameter 2, e.g. Std. Dev. or Beta 
%
% LOWERB    [Np 1] Vector, Lower Bound for the estimation 
%
% UPPERB    [Np 1] Vector, Upper Bound for the estimation  
%
%% Output
% Partition [Np 1] vector into Ne and Nc positions 
%
% indp       [Ne 1] Vector, Position indicator of estimated parameters 
% 
% con        [Nc  1] Vector, Position of parameters calibrated 
% 
% calpr      [Nc  1] Vector, calibrated parameter 
% 
% alphap     [Ne  1] ALPHA for the computation of the priors 
% betap      [Ne  1] BETA  for the computation of the priors
% 
% For the UNIFORM  ALPHAP and BETAP are given by ALPHAP and BETAP 
%
% AJ 6/25/03 
% Modified 4/27/2007 
% 1/13/2009 Add new density T which is a truncated beta. 
% See MSDBETAB. for details. Bounds of the Uniform defined in MSDTOAB.m 
% 
% =================================================================
fields=fielnames(inStru); 
dim.param=length(fields); 
postStru.cal.dim=0; 
postStru.cal.val=[];
postStru.cal.pos=[];


postStru.estimate=(1:dim.param); 

priorCell=cell(dim.param,5); 

for ii=1:dim.elem
    
    %% Extract 
    %  fieldname, distribtion, 
    %  location One, location Two, 
    %  lower and upper bound 
    fldnm=fields{ii};
    distStr=upper(deblank(char(inStru.(fldnm).dist)));
    inOne=inStru.(fldnm).mean;
    inTwo=inStru.(fldnm).std;
    lowerb=inStru.(fldnm).lowerb;
    upperb=inStru.(fldnm).upperb;
    
    %% Fill in priorCell
    priorCell(ii,1)={fldnm};
    priorCell(ii,2)={distStr};
    priorCell(ii,3)={num2str(inOne)};
    priorCell(ii,4)={num2str(inTwo)};
    priorCell(ii,5)={num2str(lowerb)};
    priorCell(ii,6)={num2str(upperb)};

    printcell(priorCell(ii,:)); 
    
    %% Calibrated Parameters 
    if strcmpi(distStr,'C')==true

        if inTwo~=0 
            error('Calibrated parameter must have std zero') 
        end 
        postStru.cal.dim=postStru.cal.dim+1;
        postStru.cal.val=[postStru.cal.val;inOne];
        postStru.cal.pos=[postStru.cal.val;ii]; 
                
    else
        %% Estimated Parameters
        if inTwo < 1e-8
            error('Estimated parameters must have positive std');
        end
        
        %% Normal
        if strcmpi(distStr,'N')==true
            name='normal';
            outOne=inOne;
            outTwo=inTwo;
            
            %% Gamma
        elseif strcmpi(distStr,'G')==true
            name='gamma';
            outTwo=(inTwo^2)/inOne;
            outOne=inOne/outTwo;
            lowerb=max(lowerb,1e-10);
            
            %% Beta (0,1)
        elseif strcmpi(distStr,'B')==true
            name='beta';
            outTwo=inOne*( (1-inOne)^2 )/(inTwo^2) - ( 1 - inOne );
            outOne=inOne*outTwo/(1-inOne);
            lowerb=max(lowerb,1e-10);
            upperb=min(upperb,1-(1e-10));
            
            %% Inverse Gamma 1
        elseif strcmpi(distStr,'I')==true
            name='invgamma';
            if inTwo > 100 ;
                inTwo=inf;
                disp('Treating the Variance of IG1 as Infinity');
            end
            [outTwo,outOne]=inverse_gamma_specification(inOne,inTwo,1);
            lowerb=max(lowerb,1e-10);
            
            %% Uniform: Location parameters are the Lower and Upper Bounds
        elseif strcmpi(distStr,'U')==true
            name='uniform';
            outOne=lowerb;
            outTwo =upperb;
            if lowerb > upperb;
                error('Lower bound in Uniform greater than Upper bound');
            end
            
            %% Wishart
        elseif strcmpi(distStr,'W')==true
            name='invwishart';
            if inTwo > 100
                outOne =4;
                outTwo =inOne*(outOne-2);
                fpraid('Treating the variance of the IW as inf');
            else
                outOne=2*(inOne^2)/(inTwo^2)+4;
                outTwo=inOne*(outOne-2);
            end
            
            %% Truncated Beta
        elseif strcmpi(distStr,'T')==true
            name='truncbeta';
            if lowerb > upperb;
                error('Lower bound in Truncated Beta greater than Upper bound');
            end
            [outOne,outTwo]=msdbetab(inOne,inTwo,lowerb,upperb);
            disp('Using Truncated Beta');
            dispaj('inOne=',inOne,' inTwo=',inTwo,' lowerBound',lowerb,' UpperB=',upperb);
            
            %% Weibull
        elseif strcmpi(distStr,'W')==true
            name='weibull';
            % Solve for the "k" parameter in weibull
            weibFunc = @(k) gamma(1+1./k).^2./gamma(1+2./k)-inOne^2/(inTwo^2+inOne^2);
            grid=(1E-3:.1:100);
            % Find an approximate solution.  Note that weibFunc is strictly
            % montone increasing so this rough minumum will be unique
            [tempVal loc] = min(abs(feval(weibFunc,grid)));
            % Find a more exact solution
            [outTwo tempfval exit_flag]=fzero(weibFunc,grid(loc));
            if exit_flag ~= 1
                error('Failed to solve for weibull parameters');
            end
            % Solve for "\lambda" parameter
            outOne=inOne/gamma(1+1/outTwo);
            disp('Using Weibull');
            dispaj('inOne=',inOne,' inTwo=',inTwo,' lowerBound',lowerb,' UpperB=',upperb);
        else
            error('Distribution name not matched')
        end
        postStru=postStruCreateSub(postStru,name,ii,outOne,outTwo,lowerb,upperb);
    end
end

if postStru.cal.dim > 0
    postStru.estimate(postStru.cal.pos)=[];
end